package com.gitee.ywj1352.gasc.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    CusAuthenticationManager authenticationManager;
    @Autowired
    AdminAuthenticationSuccessHandler adminAuthenticationSuccessHandler;
    @Autowired
    AdminAuthenticationFailureHandler adminAuthenticationFailureHandler;
    @Autowired
    private MyAuthenticationEntryPoint myAuthenticationEntryPoint;

    @Override
    protected void configure(HttpSecurity http) throws Exception { //配置策略
        AdminAuthenticationProcessingFilter adminAuthenticationProcessingFilter = new AdminAuthenticationProcessingFilter(authenticationManager, adminAuthenticationSuccessHandler, adminAuthenticationFailureHandler);
        http.formLogin().disable();
        //不需要使用 表单登录
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/login").permitAll()
                .antMatchers("/sessionOut").permitAll()
                .antMatchers("/accessDenied").permitAll()
                .antMatchers("/unLogin").permitAll()
                .antMatchers("/hah").hasAuthority("ROLE_ADMIN")
                .antMatchers("/hah2").hasAuthority("ROLE_USER")
                .antMatchers("/api/user/**").hasAuthority("ROLE_ADMIN")
                .antMatchers("/api/user2/**").hasAuthority("ROLE_USER")
                .and()
                .exceptionHandling().accessDeniedPage("/accessDenied").authenticationEntryPoint(myAuthenticationEntryPoint)
                .and()
                .logout().permitAll().invalidateHttpSession(true).deleteCookies("JSESSIONID").logoutSuccessHandler(logoutSuccessHandler())
                .and()
                .sessionManagement().invalidSessionUrl("/sessionOut").maximumSessions(10);
        http.addFilterAt(adminAuthenticationProcessingFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public LogoutSuccessHandler logoutSuccessHandler() { //登出处理
        return (httpServletRequest, httpServletResponse, authentication) -> {
            try {
                UserDetails user = (UserDetails) authentication.getPrincipal();
                log.info("USER : {} LOGOUT SUCCESS ! ", user.getUsername());
            } catch (Exception e) {
                log.error("printStackTrace", e);
            }
            httpServletResponse.sendRedirect("/login");
        };
    }

    @Bean
    public SavedRequestAwareAuthenticationSuccessHandler loginSuccessHandler() { //登入处理
        return new SavedRequestAwareAuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException, ServletException, IOException {
                UserDetails userDetails = (UserDetails) authentication.getPrincipal();
                log.info("USER : {} LOGIN SUCCESS !  ", userDetails.getUsername());
                super.onAuthenticationSuccess(request, response, authentication);
            }
        };

    }


}
